iT邦幫忙

0

kintone 外掛開發 ⑥ 透過外掛 proxy 執行外部請求 - 入門概述篇

  • 分享至 

  • xImage
  •  

在 kintone 的客製化開發中,呼叫外部 API 是一個常見的需求。不過由於瀏覽器同源政策(Same-Origin Policy)的限制,當從 kintone 的網頁中直接對外部網域發出請求時,常常會遇到 CORS(跨來源資源共用)錯誤。

關於這點,我們曾在【kintone】CORS問題與 kintone.proxy 的使用 一文中介紹過,如何透過 kintone.proxy() 方法,利用 kintone 內建的代理伺服器來繞過這項限制,成功向外部服務發送請求。

不過,如果要向需要身份驗證的 API 發送請求,就不太適合只靠 kintone.proxy() 處理。原因很簡單:認證資訊會直接暴露在使用者端的 JavaScript 程式碼中。即使這些客製化程式碼已透過 webpack 等工具打包,或已封裝進外掛檔案中,仍可能被有心人士透過瀏覽器的開發者工具檢視與擷取。雖然 kintone 本身必須登入後才能使用,但在資安要求較高的場景下,這樣的實作方式仍存在風險。

為什麼使用外掛 proxy 設定?

這時候,就輪到 kintone 外掛 API 出場了。

kintone 在 plugin API 中提供了以下方法用以設定/呼叫 proxy 請求:

透過這幾個 API,我們可以在「外掛的設定畫面」中預先設定好請求的 URL、HTTP 方法、必要的 headers(如認證用的 API Key 或 Token)與請求內容。這些資訊會被安全地儲存在外掛的設定中,並且 不會直接出現在前端程式碼中

當 kintone 應用程式需要對外部服務發送請求時,只要呼叫 kintone.plugin.app.proxy(),就可以間接使用這些已設定好的 proxy 請求,達到資料存取的效果,卻又不讓使用者端看到敏感資訊。

Plugin proxy API 的基本介紹

以下簡要說明 Plugin proxy API 的用途與基本參數,詳細範例將於後續文章中進一步說明。

setProxyConfig

kintone.plugin.app.setProxyConfig(url, method, headers, data, successCallback)

儲存執行外部 API 所需的外掛設定資訊。
當之後透過 Plug-in Proxy Request 發送請求時,使用本 API 所儲存的資訊會自動加入至該請求的 header 與 body 中。

引數 型別 必須 說明
url 字串 必須 欲執行之 API Url
method 字串 必須 執行 API 使用之 http 方法,可指定以下值:GET, POST, PUT, DELETE
headers 物件 必須 欲加入 API 請求 header 中的參數。若與執行時使用 kintone.plugin.app.proxy() 指定的 header 衝突,將以此處設定的值為主。如無需加入 header,需傳入空物件 {}
data 物件 必須 欲加入 API 請求 body 中的資料,格式為物件,內含 key-value 配對,例如:{ "key1": "value1", "key2": "value2" }。若與執行時指定的資料重複,將以此處設定的值為主。如無需加入 body,需傳入空物件 {}。無法指定巢狀物件(Object 型態)作為值。
successCallback 函式 可省略 設定成功後欲執行的回呼函式。無任何參數。若未指定此函式(為 undefinednull 或不設定),將自動導向回外掛清單頁,並顯示設定已完成的訊息;若指定了此函式,則不會導向,需由開發者自行處理畫面邏輯。

⚠️ 本 API 僅能於外掛設定頁面執行,該頁面只有應用程式管理者能存取,因此可防止非管理者存取這些儲存的資訊。

🔗 英文版官方文件:https://kintone.dev/en/docs/kintone/js-api/plugin/proxy-set-config
🔗 日文版官方文件:https://cybozu.dev/ja/kintone/docs/js-api/plugins/set-config-for-proxy


getProxyConfig

kintone.plugin.app.getProxyConfig(url, method)

此 API 可於外掛設定頁面執行,用來讀取事先透過 setProxyConfig 所儲存的 proxy 設定內容,主要包含將被加入至請求的 headersdata

引數 型別 必須 說明
url 字串 必須 欲執行之 API Url
method 字串 必須 執行 API 使用之 http 方法,可指定以下值:GET, POST, PUT, DELETE

回傳結果

成功執行時,將回傳一個包含以下參數的物件:

參數名稱 類型 說明
headers Object 先前透過 setProxyConfig() 設定的 request headers。
data Object 先前透過 setProxyConfig() 設定的 request body 內容。

若查無對應的設定(例如:未呼叫過 setProxyConfig()、URL 或方法不符),或是在不支援的頁面中執行此 API,則回傳值為 null

⚠️ 本 API 僅能於外掛設定頁面執行,該頁面只有應用程式管理者能存取,因此可防止非管理者存取這些儲存的資訊。

🔗 英文版官方文件:https://kintone.dev/en/docs/kintone/js-api/plugin/proxy-get-config
🔗 日文版官方文件:https://cybozu.dev/ja/kintone/docs/js-api/plugins/get-config-for-proxy


Plug-in Proxy Request

kintone.plugin.app.proxy(pluginId, url, method, headers, data, successCallback, failureCallback)

此 API 可用於透過外掛對外部服務發送 API 請求,並避開 CORS 限制。
請求內容(如 URL、HTTP 方法、header 與 body)必須事先透過 setProxyConfig() 儲存在外掛設定中,否則無法發送請求。
呼叫此 API 時,會執行與指定 URL、HTTP 方法相符的預存設定,並將傳入的 headers 與 data 與預存內容合併後一併送出。

引數 型別 必須 說明
pluginId 字串 必須 發送此 API 的外掛 ID。可使用 kintone.$PLUGIN_ID 取得。
url 字串 必須 欲執行之 API Url
method 字串 必須 執行 API 使用之 http 方法,可指定以下值:GET, POST, PUT, DELETE
headers 物件 必須 API 請求中要附加的 headers。這些參數會與透過 setProxyConfig() 儲存的 headers 合併送出。若不需額外指定,請設為 {}
data 物件 必須 API 請求的資料內容(body)。僅適用於 POST 與 PUT 請求,GET 和 DELETE 請忽略此參數,改將資料寫入 URL 的 QueryString。此值會與透過 setProxyConfig() 儲存的資料一併送出。
successCallback 函式 可省略 請求成功時執行的函式。會收到以下三個參數:1. 回應主體(String)2. HTTP 狀態碼(Number)3. 回應 headers(Object)若省略此參數,則會回傳一個 kintone.Promise
failureCallback 函式 可省略 請求失敗時執行的函式。收到的參數為回應主體(String)。若省略此參數,也會回傳一個 kintone.Promise

callback 寫法或省略後使用 Promise 的方式,和 kintone.proxy() 相同。
可以參考之前的文章:【kintone】CORS問題與 kintone.proxy 的使用

🔗 英文版官方文件:https://kintone.dev/en/docs/kintone/js-api/plugin/plug-in-proxy-request
🔗 日文版官方文件:https://cybozu.dev/ja/kintone/docs/js-api/plugins/kintone-plug-in-proxy


Plug-in Proxy File Upload

kintone.plugin.app.proxy.upload(pluginId, url, method, headers, data, successCallback, failureCallback)

此 API 用於透過 kintone 外掛將檔案上傳至外部服務,適用於透過 REST API 向第三方系統傳送檔案的情境。
使用方式與 kintone.plugin.app.proxy() 相同,差別僅在 data 參數用於傳送檔案(Blob/File),其格式要求詳見下方說明。
同樣需先透過 setProxyConfig() 將請求資訊儲存在外掛設定中,否則無法發送請求。

引數 型別 必須 說明
pluginId 字串 必須 發送此 API 的外掛 ID。可使用 kintone.$PLUGIN_ID 取得。
url 字串 必須 欲執行之 API Url
method 字串 必須 執行 API 使用之 http 方法,可指定以下值: POST, PUT
headers 物件 必須 API 請求中要附加的 headers。這些參數會與透過 setProxyConfig() 儲存的 headers 合併送出。若不需額外指定,請設為 {}
data 物件 必須 要傳送的上傳資料,格式如下:{ format: 'RAW', value: Blob 或 File 物件 }format 僅支援 'RAW'value 必須為 BlobFile,最大上傳檔案大小為 200MB。
successCallback 函式 可省略 請求成功時執行的函式。會收到以下三個參數:1. 回應主體(String)2. HTTP 狀態碼(Number)3. 回應 headers(Object)若省略此參數,則會回傳一個 kintone.Promise
failureCallback 函式 可省略 請求失敗時執行的函式。收到的參數為回應主體(String)。若省略此參數,也會回傳一個 kintone.Promise

🔗 英文版官方文件:https://kintone.dev/en/docs/kintone/js-api/plugin/plug-in-proxy-file-upload
🔗 日文版官方文件:https://cybozu.dev/ja/kintone/docs/js-api/plugins/kintone-plug-in-proxy-upload

Plug-in Proxy 存取資料的規則、限制與注意事項

儲存的資訊會在何時加入請求中?

使用 kintone.plugin.app.proxy().upload() 發送請求時,只有在符合以下條件時,才會將外掛設定中預先儲存的資訊(headers、data)加到請求中

  1. 應用程式相同
  2. 外掛相同(pluginId 相同)
  3. HTTP 方法相同(GET/POST/PUT/DELETE)
  4. URL 需與儲存設定的 URL 前方一致(大小寫有別)

☝️ 若儲存了多筆設定,會採用與實際請求 URL 前綴相符字元數最多 的設定。

範例:使用條件判斷

已儲存設定:

  • 設定1:https://api.example.com/,header 為 { "Content-Type": "application/x-www-form-urlencoded" }
  • 設定2:https://api.example.com/foo/,header 為 { "Content-Type": "application/json" }

實際請求的 URL 為:
https://api.example.com/foo/operate.json → 符合設定2的前綴,因此會套用其 header,最終送出:

{ "Content-Type": "application/json" }

請求 headers 的合併方式

setProxyConfig() 中已設定 header,同時於 proxy().upload() 也傳入 header,會進行合併
若 key 重複,則以 setProxyConfig() 儲存的值為優先。

範例:

// setProxyConfig() 儲存:
{ "k1": "v1" }

// proxy() 請求時指定:
{ "k2": "v2" }

// 最終送出:
{ "k1": "v1", "k2": "v2" }

請求資料(data)的合併方式

POST/PUT 方法:

  • 若傳入的 data物件型態,則會與 setProxyConfig() 儲存的資料合併。
  • 若傳入的 data字串型態,則不會進行合併,只會送出目前請求所指定的內容。

GET/DELETE 方法:

  • 不支援 data 欄位,因此會將 setProxyConfig() 儲存的資料加在 URL 的 Query String 後方。
  • 若 URL 沒有 ?,系統會自動補上。
  • 範例:
    • 設定儲存的 data 為 { "k1": "v1", "k2": "v2" }
    • 呼叫的 URL:https://api.example.com?k=v
      → 實際發送的 URL 為:https://api.example.com?k=v&k1=v1&k2=v2

當有多筆設定時的優先順序

若儲存了多筆設定,且有 key 名稱重複,會依照下列規則套用:

  • 取與請求 URL 最相符的那筆設定(前綴字元最多相符者)
  • 若 key 在 setProxyConfig() 和 proxy 請求中皆有出現,則以 setProxyConfig() 儲存的值為準(僅適用 POST/PUT 且 data 為物件時)
  • GET/DELETE 不會處理 key 衝突,會直接合併進 Query String

範例:

// 設定儲存的 header:
{ "k1": "v1", "k2": "v2" }

// proxy() 請求中指定:
{ "k2": "v2-1", "k3": "v3" }

// 最終送出:
{ "k1": "v1", "k2": "v2", "k3": "v3" }

注意事項

  • 若在 url 中指定了不存在的伺服器,將會回傳狀態碼「503」(DNS Cache Missing)的錯誤。
  • 若設定了 IP 位址限制,並希望透過此 JavaScript API 對同一子網域中的其他應用程式執行 kintone REST API,需允許 kintone 所使用的 IP 位址。有關 IP 位址的詳細資訊,請參閱此頁面:cybozu.com 所使用的網域與 IP 位址

⚠️ 請注意:此設定將允許所有 kintone 環境透過 kintone proxy API 存取該環境,以資安考量的角度來看,不建議進行此項操作

  • 使用此 API 執行外部 API 時,目的伺服器應該產生的 Cookie 並不會自動建立。
  • 若指定的 HTTP 方法為 POSTPUT,系統會自動加上「Content-Length」與「Transfer-Encoding」這兩個標頭。若在發送請求時自行指定,則會導致錯誤。

使用限制

項目 限制說明
回應 header 行數上限 最多 100 行,單行最大長度為 8,180 bytes
回應 body 大小上限 最多 10MB,超過將觸發錯誤
回應格式限制 僅支援文字資料,不支援圖片等二進位格式
憑證限制 不支援與使用自簽憑證的伺服器進行通訊

結語

相較於一般的 kintone.proxy(),Plug-in Proxy 提供了更安全的方式來隱藏認證資訊,特別適用於對資安有較高要求的應用場景。
由於這套機制涉及的條件判斷與行為細節較多,初次使用時常會遇到錯誤,建議可搭配本系列文章,以及日文、英文官方文件多加測試與練習。
熟悉之後,將能靈活應用在各類第三方 API 串接場景,讓 kintone 的整合能力更上一層樓。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言